/*
 * DoDictionary.h
 *
 *  Created on: Oct 18, 2012
 *      Author: wtao
 */

#ifndef DODICTIONARY_H_
#define DODICTIONARY_H_

#include "_DoCompositeObject.h"
#include "DoName.h"
#include <unordered_map>

class DoDictionary : public onTokenListener, public _DoCompositeObject
{
public:
	typedef	unordered_map< CRefPtr< _DoObject >, CRefPtr< _DoObject >, DoName > CObjMap;
	typedef	unordered_map< CRefPtr< _DoObject >, CRefPtr< _DoObject >, DoName >::iterator CDictIter;
	typedef pair<CObjMap::iterator, CObjMap::iterator> CDictRange;
	typedef pair< CRefPtr< _DoObject >, CRefPtr< _DoObject > > CDictEntry;

protected:
	DoDictionary(const DoDictionary&);
	DoDictionary& operator=(const DoDictionary&);

	CObjMap mDict;
	
	int mParseEnd;
	
	bool mExpectKey;
	
	CRefPtr< _DoObject > mTempKey;
public:
	DoDictionary(const std::string &name);
	virtual ~DoDictionary();

	virtual void clear() {
		mDict.clear();
	}

	CRefPtr<_DoObject > get(CRefPtr<_DoObject > key) {
		return mDict[key];
	}

	void put(CRefPtr< _DoObject > key, CRefPtr< _DoObject > value) {
		mDict[key] = value;
	}
	
	CDictIter begin() {
		return mDict.begin();
	}
	
	CDictIter end() {
		return mDict.end();
	}

	virtual void remove(CRefPtr< _DoObject > key) {
		mDict.erase(key);
	}

	virtual size_t size() const {
		return mDict.size();
	}

	bool containsKey(CRefPtr< _DoObject > key) {
		return mDict.count(key) != 0;
	}
	
	virtual std::string _debug_dump() const;
	
	virtual onTokenListener::eContinueParse onChar(int currChar) {
		if (currChar == '>')
			mParseEnd ++;
		else
			mParseEnd = 0;
		
		if (mParseEnd == 2) 
			return onTokenListener::eStop;
		if (mParseEnd == 1)
			return onTokenListener::eLetMeSeeOneMore;
		return onTokenListener::eContinue;
	}

	virtual void onToken(CRefPtr< _DoObject > token) {
		if (mExpectKey) {
			mTempKey = token;
			mExpectKey = false;
		} else {
			put(mTempKey, token);
			mExpectKey = true;
		}
	}
};

#endif /* DODICTIONARY_H_ */
